package com.dc.bobaoge.project.v3.to.v2.business.core;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.dc.bobaoge.base.entity.advertisement.po.Advertisement;
import com.dc.bobaoge.base.entity.advertisement.po.AdvertisementRelease;
import com.dc.bobaoge.base.mapper.advertisement.AdvertisementMapper;
import com.dc.bobaoge.base.mapper.advertisement.AdvertisementReleaseMapper;
import com.dc.bobaoge.common.em.MessageTemplateEnum;
import com.dc.bobaoge.project.base.core.constant.BaseInfoConstant;
import com.dc.bobaoge.project.base.core.old.entity.OldCoreAdvertisement;
import com.dc.bobaoge.project.base.core.old.entity.OldCoreAdvertisementTimeLog;
import com.dc.bobaoge.project.base.core.old.entity.OldCoreAdvertisementType;
import com.dc.bobaoge.project.base.core.old.mapper.OldCoreAdvertisementMapper;
import com.dc.bobaoge.project.base.core.old.mapper.OldCoreAdvertisementTimeLogMapper;
import com.dc.bobaoge.project.base.core.old.mapper.OldCoreAdvertisementTypeMapper;
import com.dc.bobaoge.project.v3.to.v2.business.core.util.AdvertisementCommonUtil;
import com.dc.bobaoge.project.v3.to.v2.business.core.util.V3ToV2MessageCommonUtil;
import com.own.business.sync.trigger.base.entity.SyncTrigger;
import com.own.business.sync.trigger.base.method.ResolveMethod;
import com.own.component.common.exception.BusinessSimpleException;
import com.own.component.common.util.list.ListUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * AdvertisementResolveMethod
 *
 * @author chenxueli
 * @date 2024-01-13 10:23:44
 */
@Slf4j
@Component
public class AdvertisementResolveMethod implements ResolveMethod {

    @Resource
    private AdvertisementMapper advertisementMapper;
    @Resource
    private AdvertisementReleaseMapper advertisementReleaseMapper;

    @Resource
    private OldCoreAdvertisementMapper oldCoreAdvertisementMapper;
    @Resource
    private OldCoreAdvertisementTypeMapper oldCoreAdvertisementTypeMapper;
    @Resource
    private OldCoreAdvertisementTimeLogMapper oldCoreAdvertisementTimeLogMapper;

    @Resource
    private V3ToV2MessageCommonUtil v3ToV2MessageCommonUtil;

    /**
     * 修改的处理方法
     *
     * @param trigger 日志信息
     */
    @Override
    public void update(SyncTrigger trigger) {
        var advertisement = advertisementMapper.selectOneWithoutLogicDelete(trigger.getTargetId());
        if (advertisement == null) {
            throw new BusinessSimpleException("广告信息未查询到" + trigger.getTargetId());
        }
        // 查询旧数据库中是否有这条数据
        var adv = oldCoreAdvertisementMapper.selectById(trigger.getTargetId());
        if (adv == null) {
            // 执行新增操作
            add(trigger, advertisement);
            return;
        }
        resolve(trigger, advertisement, adv);
        oldCoreAdvertisementMapper.updateById(adv);
    }

    /**
     * 添加操作
     *
     * @param trigger       日志信息
     * @param advertisement 广告信息
     */
    private void add(SyncTrigger trigger, Advertisement advertisement) {
        var adv = resolve(trigger, advertisement, null);
        oldCoreAdvertisementMapper.insert(adv);
    }

    /**
     * 处理方法
     *
     * @param trigger       日志信息
     * @param advertisement 广告信息
     * @param adv           旧广告信息
     * @return 旧广告信息
     */
    private OldCoreAdvertisement resolve(SyncTrigger trigger, Advertisement advertisement, OldCoreAdvertisement adv) {
        var isAdd = adv == null;
        if (isAdd) {
            adv = new OldCoreAdvertisement();
        }
        // 广告主信息
        adv.setAdvmsgId(advertisement.getId());
        adv.setAdvmsgCostId(advertisement.getFkChargeModeId() == null ? 0 : advertisement.getFkChargeModeId());
        // 收费类型新版默认为固定日期，值为1
        adv.setCosttypeId(1);
        // 新 投放位置 1=轮播图 2=即时消息 旧 广告类型 1=轮播 2、3=消息广告。所以直接赋值就行
        adv.setAdvmsgTypeId(advertisement.getPlacement());
        adv.setAdvmsgUserId(advertisement.getFkUserId());
        // 需要根据频道id和顺序查询广告位id
        var moldId = AdvertisementCommonUtil.MoldChannelShip.getMoldByChannel(advertisement.getFkChannelId());
        var sequence = advertisement.getPlacementSequence() + 1;
        // 查询对应的typeId
        {
            var wrapper = new LambdaQueryWrapper<OldCoreAdvertisementType>()
                    .eq(OldCoreAdvertisementType::getAdvTypeId, advertisement.getPlacement())
                    .eq(OldCoreAdvertisementType::getAdvMold, moldId)
                    .eq(OldCoreAdvertisementType::getTypesubNumber, sequence)
                    .last("limit 1");
            var type = oldCoreAdvertisementTypeMapper.selectOne(wrapper);
            if (type != null) {
                adv.setAdvmsgSeatId(type.getTypesubId());
            }
        }
        adv.setAdvmsgMoldId(moldId);
        adv.setAdvmsgContent(advertisement.getContent());
        // 设置主图为横图
        adv.setAdvmsgMaster(advertisement.getImageHorizontalUrl());
        // 查询媒资信息
        var imageUrls = v3ToV2MessageCommonUtil.getImageUrls(advertisement.getId(), advertisement.getSharding(), MessageTemplateEnum.ADVERTISEMENT);
        adv.setAdvmsgImages(String.join(BaseInfoConstant.IMAGE_SPILT, ListUtil.Spilt.to(imageUrls, ",")));
        adv.setAdvmsgDate(advertisement.getPublishTime());
        adv.setAdvmsgVerifyDate(advertisement.getAuditTime());
        adv.setAdvmsgAddress(advertisement.getAddress());
        adv.setAdvmsgReason(advertisement.getAuditRemark());
        adv.setAdvmsgCost(advertisement.getRkChargeModeName() == null ? "" : advertisement.getRkChargeModeName());
        adv.setAdvmsgSeatNumber(sequence);
        adv.setAdvmsgUserPhone(advertisement.getRfContactPhone());
        // 查询广告的投放日期列表
        var wrapper = new LambdaQueryWrapper<AdvertisementRelease>()
                .eq(AdvertisementRelease::getFkAdvertisementId, advertisement.getId())
                .orderByAsc(AdvertisementRelease::getReleaseDate);
        var releaseList = advertisementReleaseMapper.selectList(wrapper);
        if (!releaseList.isEmpty()) {
            // 获取最后一天
            var lastDay = releaseList.getLast().getReleaseDate();
            adv.setAdvmsgOvertime(LocalDateTime.of(lastDay, LocalTime.MAX));
        }
        adv.setAdvmsgAnsw((short) 1);
        // 设置广告的状态信息
        buildAuditStatus(advertisement, adv, releaseList);
        adv.setAdvmsgRefuseReson(advertisement.getAuditRemark());
        // 删除原有的投放日期数据
        if (!isAdd) {
            var timeLogWrapper = new LambdaQueryWrapper<OldCoreAdvertisementTimeLog>().eq(OldCoreAdvertisementTimeLog::getLogAdvId, advertisement.getId());
            oldCoreAdvertisementTimeLogMapper.delete(timeLogWrapper);
        }
        // 广告投放日期时间
        var addLogList = releaseList.stream().map(item -> {
            var log = new OldCoreAdvertisementTimeLog();
            log.setLogAdvId(advertisement.getId());
            log.setLogDate(LocalDateTime.of(item.getReleaseDate(), LocalTime.MIN));
            log.setLogTime(item.getPublishTime());
            return log;
        }).collect(Collectors.toList());
        oldCoreAdvertisementTimeLogMapper.insertBatch(addLogList);
        // 返回广告的主信息
        return adv;
    }

    /**
     * 设置状态信息
     * <p>
     * 旧广告状态 0=审核中 1=正在进行 2=手动结束投放 3=管理员拒绝 4=管理员删除 5=已结束 6=未开始 7=不是购买当天的广告 9=没支付
     * <p>
     * 新广告状态 1=待审核 2=审核通过 3=审核不通过 4=完成 5=已违规 6=锁定 7=待支付 8=管理员下架 9=用户下架
     *
     * @param advertisement        广告信息
     * @param oldCoreAdvertisement 旧的广告信息
     * @param releaseList          投放日期列表
     */
    private void buildAuditStatus(Advertisement advertisement, OldCoreAdvertisement oldCoreAdvertisement, List<AdvertisementRelease> releaseList) {
        switch (advertisement.getAuditStatus()) {
            case 2, 4: {
                var now = LocalDate.now();
                checkDate:
                if (releaseList.isEmpty()) {
                    oldCoreAdvertisement.setAdvmsgState(5);
                } else {
                    // 具体处理
                    releaseList.sort(Comparator.comparing(AdvertisementRelease::getReleaseDate));
                    // 获取最小的日期
                    var date1 = releaseList.getFirst();
                    if (now.isBefore(date1.getReleaseDate())) {
                        oldCoreAdvertisement.setAdvmsgState(6);
                        break checkDate;
                    }
                    var date2 = releaseList.getLast();
                    if (now.isAfter(date2.getReleaseDate())) {
                        oldCoreAdvertisement.setAdvmsgState(5);
                    }
                    oldCoreAdvertisement.setAdvmsgState(1);
                }
                oldCoreAdvertisement.setAdvmsgVerifyDate(advertisement.getAuditTime());
                break;
            }
            case 3: {
                oldCoreAdvertisement.setAdvmsgState(3);
                oldCoreAdvertisement.setAdvmsgVerifyDate(advertisement.getAuditTime());
                break;
            }
            case 5: {
                oldCoreAdvertisement.setAdvmsgState(4);
                oldCoreAdvertisement.setAdvmsgVerifyDate(advertisement.getAuditTime());
                break;
            }
            case 7: {
                oldCoreAdvertisement.setAdvmsgState(9);
                break;
            }
            case 8, 9: {
                oldCoreAdvertisement.setAdvmsgState(2);
                oldCoreAdvertisement.setAdvmsgVerifyDate(advertisement.getAuditTime());
                break;
            }
            case 1:
            default: {
                oldCoreAdvertisement.setAdvmsgState(0);
                oldCoreAdvertisement.setAdvmsgVerifyDate(null);
                break;
            }
        }
    }

    /**
     * 名称信息
     *
     * @return 名称
     */
    @Override
    public String name() {
        return "advertisement";
    }

}
